#include "trymessages.h"

void handleTryMessage(unsigned char * message, struct addressPort senderInfo) {

	unsigned char filename[MAX_NAME];
	memset(filename, 0, sizeof(filename));
	int messageIndex = 0;

	// Loop variable
	int i;

	// Determine the filename provided by the try message.
	strcpy((char *) filename, (char *) message+2);
		
	// Add 1 initially to account for the selector byte in the try message.
	messageIndex = 1 + strlen((char *) filename)+2;

	// Handle multi-byte peer count.
	// The amount of peers that have corresponding file provided in the try message.
  short int peerCount;
  short int * peerCountPtr;
  peerCountPtr = (short int *) &message[6];
  peerCount = ntohs(*peerCountPtr);

  // The peer count value is 2-bytes long so compute using two char elements of the message.
	messageIndex += 2;
		
	int isOutstandingRequest = false;
	struct node * iterator = createIterator(outstandingRequestsList);
	struct node * freeIterator = iterator;
	
	// Handle try messages only if it is an outstanding request.
	if (searchOutstandingReqList(filename, message) == true) {
		isOutstandingRequest = true;
	}
		
	free(freeIterator);
	
	if (isOutstandingRequest == true) {	

		unsigned long int address;
		unsigned long int * addressPtr;
		unsigned short int port;
		unsigned short int * portPtr;
			
		// Add <peer, filename> pair entries into content directory if not a duplicate entry.
		for (i = 0; i < peerCount; i++) {

			struct addressPort tempAddress;
			// Parse 4 bytes of char for the peer ip address.
			addressPtr = (unsigned long int *) &message[messageIndex];
			address = ntohl(*addressPtr);
			tempAddress.address = address;
			messageIndex += 4;
			
			// Parse 2 bytes of char for the peer port number.
			portPtr = (unsigned short int *) &message[messageIndex];
			port = ntohs(*portPtr);
			tempAddress.port = port;
			messageIndex += 2;
			
			// If is not a duplicate content directory entry, add it to the list.
			if (searchContentDir(filename, tempAddress) == false) {
				struct node * newContentDirectoryItem = createContentDirItem(filename, tempAddress);
				
				if (debug) {
					struct contentDir * ncdi = newContentDirectoryItem->payload;
					printf("handleTryMessage function: ncdi name is %s, ip addresss is %u, port number is %u\n", ncdi->name, ncdi->address, ncdi->port);
				}
				
				push(&contentDirectoryList, newContentDirectoryItem);
			}
			
		}
		
		// Test code: Prints current content directory all pushes have been executed on the list.
		if (debug) {
			printf("handleTryMessage function: Current content directory size is %d\n", contentDirectoryList.size);
			struct node * myIterator = createIterator(contentDirectoryList);
			struct node * freeMyIterator = myIterator;
			while (hasNext(myIterator)) {
				next(&myIterator);
				struct contentDir * cd = (struct contentDir *) myIterator->payload;
				printf("handleTryMessage function: Current content directory entry: %s | %u | %u", cd->name, cd->address, cd->port);
			}
			free(freeMyIterator);
		}
	}
}